package com.zs.propertymanage.service.impl.impl;

import com.zs.propertymanage.dataObj.DTO;
import com.zs.propertymanage.dataObj.GeneralExtra;
import com.zs.propertymanage.dataObj.R;
import com.zs.propertymanage.dataObj.entity.*;
import com.zs.propertymanage.dataObj.param.StatisticItem;
import com.zs.propertymanage.dataObj.workorderExtra.WorkOrderCategory;
import com.zs.propertymanage.dataObj.workorderExtra.WorkOrderProcess;
import com.zs.propertymanage.mapper.HouseMapper;
import com.zs.propertymanage.mapper.MessageMapper;
import com.zs.propertymanage.mapper.TenantMapper;
import com.zs.propertymanage.mapper.WorkOrderMapper;
import com.zs.propertymanage.service.impl.OrgService;
import com.zs.propertymanage.service.impl.TenantService;
import com.zs.propertymanage.utils.MD5Util;
import com.zs.propertymanage.websocket.WebSocketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import java.util.UUID;

@Service
public class TenantServiceImpl implements TenantService {

    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private HouseMapper houseMapper;

    @Autowired
    private WorkOrderMapper workOrderMapper;
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private OrgService orgService;

    @Override
    public R getAllTenantWithPlain() {
        List<Tenant> list = tenantMapper.getAllTenantWithPlain();
        return list.size() > 0 ? R.ok("查询租户成功", list) : R.error("查询租户失败");
    }

    @Override
    public R getAllTenantWithCondition(String search, Integer currentPage, Integer pageSize) {
        Integer start = (currentPage - 1) * pageSize;
        List<Tenant> list = tenantMapper.getAllTenantWithCondition(search, start, pageSize);
        Integer total = tenantMapper.getCountWithCondition(search, start, pageSize);
        DTO<Tenant> tenantDto = new DTO(list, total);

        return total > 0 ? R.ok("查询租户成功", tenantDto) : R.error("查询租户失败");
    }

    @Override
    public R addTenant(Tenant tenant) {
        String pwd = tenant.getPassword();
        // 密码MD5加密
        if (pwd != null && !pwd.equals("")) {
            tenant.setPassword(MD5Util.MD5Encrypt(pwd));
        } else {
            return R.error("密码不能为空");
        }
        tenant.setId(UUID.randomUUID().toString());
        int i = tenantMapper.addTenant(tenant);
        return i > 0 ? R.ok("添加租户成功") : R.error("添加租户失败");
    }

    @Override
    public R updateTenant(Tenant tenant) {
        int i = tenantMapper.updateTenant(tenant);
        return i > 0 ? R.ok("修改租户成功") : R.error("修改租户失败");
    }

    @Override
    public R deleteTenantById(String id) {
        int i = tenantMapper.deleteTenantById(id);
        return i > 0 ? R.ok("删除租户成功") : R.error("删除租户失败");
    }

    @Override
    public R getTenantStat(String tenantId) {

        // 最终返回数据集合
        TreeMap<String, List<StatisticItem>> resultMap = new TreeMap<>();

        // 房屋数据
        // 查总房屋数
        List<StatisticItem> totalHouse = new ArrayList<>();    // 房屋总数结果集合
        totalHouse.add(new StatisticItem("总房屋数", houseMapper.getCountOfTenant(tenantId)));
        // 查各房屋类型下房间数
        List<StatisticItem> houseTypeStatList = new ArrayList<>(); // 房屋类型结果集合
        List<GeneralExtra> houseTypeList = houseMapper.getAllHouseType();  // 房屋类型列表
        for (GeneralExtra houseType : houseTypeList)   // 查询每个房屋类型下的房屋数
            houseTypeStatList.add(new StatisticItem(houseType.getName(), houseMapper.getCountOfTenantByType(tenantId, houseType.getId())));
        // 查各房间状态下房间数
        List<StatisticItem> houseStatusStatList = new ArrayList<>();   // 房屋状态结果集合
        List<GeneralExtra> houseStatusList = houseMapper.getAllHouseStatus();    // 房屋状态列表
        for (GeneralExtra houseStatus : houseStatusList) // 查询每个状态下的房屋数
            houseStatusStatList.add(new StatisticItem(houseStatus.getName(), houseMapper.getCountOfTenantByStatus(tenantId, houseStatus.getId())));

        resultMap.put("totalHouse", totalHouse);
        resultMap.put("byHouseType", houseTypeStatList);
        resultMap.put("byHouseStatus", houseStatusStatList);

        //工单数据
        // 查总工单数
        List<StatisticItem> totalWorkOrder = new ArrayList<>();    // 总工单数结果集合
        totalWorkOrder.add(new StatisticItem("总工单数", workOrderMapper.getCountOfTenant(tenantId)));
        // 查各工单分类下工单数
        List<StatisticItem> workOrderCategoryStatList = new ArrayList<>(); // 工单分类结果集合
        List<WorkOrderCategory> workOrderCategoryList = workOrderMapper.getAllCategory();   // 工单分类集合
        for (WorkOrderCategory workOrderCategory : workOrderCategoryList)   // 查询每个分类下的工单数
            workOrderCategoryStatList.add(new StatisticItem(workOrderCategory.getName(), workOrderMapper.getCountOfTenantByCategory(tenantId, workOrderCategory.getId())));
        // 查各工单状态下工单数
        List<StatisticItem> workOrderCompleteStatusStatList = new ArrayList<>();   // 工单状态结果集合
//        List<WorkOrderStatus> workOrderStatusList = workOrderMapper.getAllWorkOrderStatus();    // 工单状态集合

        String completeStatusName; // 完成状态名称
        for (int i = 1; i <= 3; i++) {  // 查询每个完成状态下的工单数 1-待接收 2-处理中 3-已完成
            if (i == 1) completeStatusName = "待接收";
            else if (i == 2) completeStatusName = "处理中";
            else completeStatusName = "已完成";
            workOrderCompleteStatusStatList.add(new StatisticItem(completeStatusName, workOrderMapper.getCountOfTenantByCompleteStatus(tenantId, i)));
        }
        resultMap.put("totalWorkOrder", totalWorkOrder);
        resultMap.put("byWorkOrderCategory", workOrderCategoryStatList);
        resultMap.put("byWorkOrderCompleteStatus", workOrderCompleteStatusStatList);

        return resultMap.size() > 0 ? R.ok("查询租户统计概览成功", resultMap) : R.error("查询租户统计概览失败");
    }

    @Override
    public R getHouseByTenantId(String id, String search, Integer currentPage, Integer pageSize) {
        Integer start = (currentPage - 1) * pageSize;
        List<House> list = houseMapper.getHouseByTenantId(id, search, start, pageSize);
        Integer total = houseMapper.getHouseCountByTenantId(id, search);
        return total > 0 ? R.ok("查询租户房屋成功", new DTO<>(list, total)) : R.error("查询租户房屋失败");
    }

    @Override
    public R getRentableHouse(String search, Integer currentPage, Integer pageSize) {
        Integer start = (currentPage - 1) * pageSize;
        List<House> list = houseMapper.getRentableHouse(search, start, pageSize);
        Integer total = houseMapper.getCountOfRentableHouse(search);
        return total > 0 ? R.ok("查询可租房屋成功", new DTO<>(list, total)) : R.error("查询可租房屋失败");
    }

    @Override
    public R rentHouse(String tenantId, String houseId) {
        return houseMapper.rentHouse(tenantId, houseId) > 0 ? R.ok("租房成功") : R.error("租房失败");
    }

    @Override
    public R stopRent(String houseId) {
        return houseMapper.stopRent(houseId) > 0 ? R.ok("停止租房成功") : R.error("停止租房失败");
    }

    @Override
    public R updateHouseStatus(String houseId, Integer statusId) {
        return houseMapper.updateHouseStatus(houseId, statusId) > 0 ? R.ok("修改房屋状态成功") : R.error("修改房屋状态失败");
    }

    @Override
    public R getWorkOrderByTenantId(String id, String search, Integer currentPage, Integer pageSize) {
        Integer start = (currentPage - 1) * pageSize;
        List<WorkOrder> list = workOrderMapper.getWorkOrderByTenantId(id, search, start, pageSize);
        Integer total = workOrderMapper.getWorkOrderCountByTenantId(id, search);
        return total > 0 ? R.ok("查询租户工单成功", new DTO<>(list, total)) : R.error("该租户下未查询到工单数据~");
    }

    @Override
    public R getAllHouseByTenantId(String tenantId) {
        List<House> list = houseMapper.getAllHouseByTenantId(tenantId);
        return list.size() > 0 ? R.ok("查询租户所有房屋成功", list) : R.error("该租户下未查询到房屋数据~");
    }

    @Override
    public R createWorkOrder(String tenantId, Integer houseId, Integer workOrderCategoryId, String orderRemark) {
        // 获取一些初始工单信息
        String uuid = UUID.randomUUID().toString();   // 生成工单id
        WorkOrderCategory category = workOrderMapper.getCategoryById(workOrderCategoryId);  // 获取工单分类信息
        if (category.getFlow() == null || category.getFlow().equals(""))    // 判断分类是否有配置流程
            return R.error("所选工单分类未配置流程");
        String[] flows = category.getFlow().split(","); // 工单分类对应的流程id列表
        // 完善工单对象信息
        WorkOrder workOrder = new WorkOrder();
        workOrder.setId(uuid);    // 工单id
        workOrder.setHouseId(houseId);  // 房屋id
        workOrder.setSubmitterId(tenantId); // 提交人id
        workOrder.setOrderRemark(orderRemark);  // 工单备注
        workOrder.setCategoryId(workOrderCategoryId);   // 工单分类id
        workOrder.setOrderTime(LocalDateTime.now());    // 工单提交时间

        StringBuilder process = new StringBuilder();
        // 根据工单分类对应的流程来预填充process
        for (int i = 0; i < flows.length; i++) {
            WorkOrderProcess workOrderProcess = new WorkOrderProcess();
            workOrderProcess.setStatusId(Integer.parseInt(flows[i]));
            workOrderProcess.setStatusName(workOrderMapper.getWorkOrderStatusById(workOrderProcess.getStatusId()).getName());
            workOrderProcess.setStartTime(0L);
            workOrderProcess.setHandler("");
            workOrderProcess.setRemark("");
            workOrderProcess.setCompleteStatus(0);
            if (i == 0) process.append(workOrderProcess);
            else process.append("&process-split&").append(workOrderProcess);
        }
        workOrder.setProcess(process.toString());
        // 新建工单
        Integer result = workOrderMapper.addWorkOrder(workOrder);

        // 消息通知到满足组织范围要求和工单职责范围要求的员工
        // 1. 获取该工单所属的组织及所有子组织id列表
        List<Integer> resultOrgList = orgService.getChildrenIdList(houseMapper.getHouseById(houseId).getOrgId());

        // 消息通知
        if (result > 0) {
            // 2. 获取该工单所属分类下的所有职责员工
            List<Employee> categoryDuty = workOrderMapper.getCategoryDutyObj(workOrderCategoryId);
            for (Employee emp : categoryDuty) {
                // 3. 判断遍历的员工所属组织是否在该工单的组织范围内
                if (resultOrgList.contains(emp.getOrgId())) {
                    Message message = new Message(
                            UUID.randomUUID().toString(),
                            "新的可接收工单",
                            LocalDateTime.now(),
                            category.getName() + "-" + orderRemark,
                            Message.TYPE_EMPLOYEE,
                            emp.getId(),
                            Message.TYPE_SYSTEM,
                            Message.ID_SYSTEM
                    );
                    messageMapper.addMessage(message);
                    // 消息通知
                    WebSocketService.sendTextMessage(emp.getId(), "您有新的工单可以接受~"); // 人员id改为了uuid，具有唯一性，不需要附加身份了
                }
            }
        }
        return result > 0 ? R.ok("新建工单成功") : R.error("新建工单失败");
    }

    @Override
    public R getTenantById(String id) {
        Tenant tenant = tenantMapper.getTenantById(id);
        return tenant != null ? R.ok("查询租户信息成功", tenant) : R.error("查询租户信息失败");
    }
}
